import javax.swing.*;
import java.awt.Font;
import java.awt.event.*;

class Jsuanfu extends JFrame implements ActionListener {
    private JTextArea ta = new JTextArea(18, 50);
    ;
    private JTextField tf;
    private JButton jb1;
    private JButton jb2;
    private JLabel jl1;
    private JLabel jl2;
    char[] a = new char[50];
    char[] s = new char[50];
    int j, k, z, p = 0;
    char m;
    boolean f = true;
    String st1 = "", st2 = "", st3 = "";

    public int table[][] = {{2, 1, 1, 1, 1, 2, 2},
            {2, 2, 1, 1, 1, 2, 2},
            {2, 2, 1, 1, 1, 2, 2},
            {2, 2, 2, -1, -1, 2, 2},
            {1, 1, 1, 1, 1, 0, -1},
            {2, 2, 2, -1, -1, 2, 2},
            {1, 1, 1, 1, 1, -1, 0}};

    public Jsuanfu() {
        super("算符优先分析器");
        this.setSize(600, 500);
        this.setLocation(200, 150);
        this.setLayout(null);
        tf = new JTextField(30);
        jb1 = new JButton("清空文本区");
        jb2 = new JButton("优先分析");
        jl1 = new JLabel("输入字符串：");
        jl2 = new JLabel("分析结果：");
        jl1.setFont(new Font("楷书", Font.BOLD, 14));
        jl2.setFont(new Font("楷书", Font.BOLD, 14));
        jl1.setSize(100, 25);
        jl1.setLocation(10, 10);
        this.add(jl1);
        tf.setSize(400, 25);
        tf.setLocation(120, 10);
        this.add(tf);
        jl2.setSize(90, 25);
        jl2.setLocation(10, 40);
        this.add(jl2);
        ta.setEditable(false);
        JScrollPane sc = new JScrollPane(ta, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        sc.setSize(580, 350);
        sc.setLocation(10, 70);
        this.add(sc);
        jb1.setBounds(100, 430, 100, 25);
        jb2.setBounds(400, 430, 100, 25);
        this.add(jb1);
        this.add(jb2);
        ta.append("  步骤" + "\t" + "栈" + "\t" + "当前符号" + "\t" + "剩余输入串" + "\t" + "移进或归约" + "\n");
        jb1.addActionListener(this);
        jb2.addActionListener(this);
        this.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == jb1) {
            ta.setText("");
            tf.setText("");
            ta.append("  步骤" + "\t" + "栈" + "\t" + "当前符号" + "\t" + "剩余输入串" + "\t" + "移进或归约" + "\n");
            p = 0;
            f = true;
        }
        if (e.getSource() == jb2) {
            int n1 = 0;
            z = 0;
            String st = tf.getText();
            char[] b = new char[st.length()];
            for (int l = 0; l < st.length(); l++) {
                b[l] = st.charAt(l);
                a[l] = st.charAt(l);
                n1 = l;
            }
            for (int d = n1 + 1; d < 50; d++)
                a[d] = '#';
            k = 1;
            s[k] = '#';
            while (z < st.length() + 1 && f) {
                if (a[z] == '+' || a[z] == '*' || a[z] == '^' || a[z] == 'i' || a[z] == '(' || a[z] == ')' || a[z] == '#')
                    e();
                else {
                    ta.append("出错");
                    f = false;
                }
                z++;
            }
        }
    }

    int findChar(char b) {
        int t = -1;
        switch (b) {
            case '+':
                t = 0;
                break;
            case '*':
                t = 1;
                break;
            case '^':
                t = 2;
                break;
            case 'i':
                t = 3;
                break;
            case '(':
                t = 4;
                break;
            case ')':
                t = 5;
                break;
            case '#':
                t = 6;
        }
        return t;
    }

    void e() {
        if (s[k] == '+' || s[k] == '*' || s[k] == '^' || s[k] == 'i' || s[k] == '(' || s[k] == ')' || s[k] == '#')
            j = k;
        else j = k - 1;
        int x1 = findChar(s[j]);
        int y1 = findChar(a[z]);
        if (table[x1][y1] == 2) {
            y();
            return;
        } else
            n();
        return;

    }

    void y() {
        m = s[j];
        if (s[j - 1] == '+' || s[j - 1] == '*' || s[j - 1] == '^' || s[j - 1] == 'i' || s[j - 1] == '(' || s[j - 1] == ')' || s[j - 1] == '#')
            j = j - 1;
        else j = j - 2;
        int x2 = findChar(s[j]);
        int y2 = findChar(m);
        if (table[x2][y2] == 1) {
            int gb;
            String st4 = "";
            for (gb = j + 1; gb <= k; gb++)
                st4 = st4 + st4.valueOf(s[gb]);
            if (st4.equals("N+N") || st4.equals("N*N") || st4.equals("N^N") || st4.equals("(N)") || st4.equals("i")) {
                output();
                ta.append("    " + st1 + "\t" + st2 + "\t" + a[z] + "\t" + st3 + "\t" + " 归约 " + "\n");
                k = j + 1;
                s[k] = 'N';

                st1 = "";
                st2 = "";
                st3 = "";
                e();
                return;
            } else {
                f = false;
                ta.append("出错");
                return;
            }
        } else y();
        return;

    }

    void n() {
        int x3 = findChar(s[j]);
        int y3 = findChar(a[z]);
        if (table[x3][y3] == 1) {
            output();
            ta.append("    " + st1 + "\t" + st2 + "\t" + a[z] + "\t" + st3 + "\t" + " 移进 " + "\n");
            k = k + 1;
            s[k] = a[z];
            st1 = "";
            st2 = "";
            st3 = "";
            return;
            } else if (table[x3][y3] == 0) {
                if (table[x3][6] == 0) {
                    if (s[j + 1] == 'N') {
                        output();
                        ta.append("    " + st1 + "\t" + st2 + "\t" + a[z] + "\t" + st3 + "\t" + " 接受 " + "\n");
                    st1 = "";
                    st2 = "";
                    st3 = "";
                    return;
                } else {
                    f = false;
                    ta.append("出错");
                    return;
                }
            } else {
                output();
                ta.append("    " + st1 + "\t" + st2 + "\t" + a[z] + "\t" + st3 + "\t" + " 移进 " + "\n");
                k = k + 1;
                s[k] = a[z];

                st1 = "";
                st2 = "";
                st3 = "";
                return;
            }
        } else {
            f = false;
            ta.append("出错");
            return;
        }
    }

    void output() {
        p++;
        st1 = String.valueOf(p);
        for (int w = 1; w <= k; w++)
            st2 = st2 + st2.valueOf(s[w]);
        if (a[z] == '#')
            st3 = "";
        else {
            for (int v = z + 1; a[v] != '#'; v++)
                st3 = st3 + st3.valueOf(a[v]);
            st3 = st3 + st3.valueOf('#');
        }
    }

    public static void main(String[] args) {
        try {
            for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    System.out.println(info.getClassName());
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (Exception e) {
            System.out.println(e);
        }
        new Jsuanfu();
    }
}
